#!/usr/bin/env python2
# -*- coding: utf-8 -*-


import sys, os, shutil
import socket, ssl

args = sys.argv[1:]
usagedescription = "rsnapssl [-c <config>] timeinterval"
mode=""
timeinterval = ""
configpath = ""
for i in args:
    if mode == "":
        if i == "-c":
            mode = "config"
            continue
        else:
            if timeinterval!="":
                raise Exception("only one timeinterval allowed. Usage: %s"%usagedescription
            timeinterval = i
    elif mode == "config":
        configpath = i
    
if timeinterval == "":
    raise Exception("no timeinterval passed! Usage: %s"%usagedescription)
if configpath == "":
    #use default path: ~/.rsnapssl/config
    #what is ~:
    if "win" in sys.platform.lower():
        homepath = os.environ['HOMEPATH']
    else:
        homepath = os.environ["HOME"]
    configpath = os.path.join(homepath, ".rsnapssl", "config")
    #create file if not existing:
    if not os.path.exists(configpath):
        #mkdirs:
        try:
            os.makedirs(os.path.join(homepath, ".rsnapssl"))
        except:
            pass
        #copy config file:
        shutil.copy(configsourcepath, configpath)
#now read config:
configinhalt = open(configpath).readlines()


snapshot_root = ""
no_create_root = 0
retains = []
logfile=""
port = ""
remote_server = ""
verboselevel=1 #only important stuff ; 0 = quiet, 2 = also warnings, 3=everything
excludes = []
for line in configinhalt:
    line = line.split()
    if line[0].startswith("#"):
        #comment line:
        continue
    if len(line)>3:
        print "Warning: only max 3 Words per Line allowed!"
        print "Warning on line:", line
    if len(line)>3 or len(line)<2:
        continue
    #snapshot_root:
    if line[0] == "snapshot_root":
        snapshot_root = line[1]
    #no_create_root:
    if line[0] == "no_create_root":
        no_create_root = int(line[1])
    #retain: (timeintervals)
    if line[0] == "retain":
        retains.append((line[1], int(line[2])))
    #logfile:
    if line[0] == "logfile":
        logfile = line[1]
    #verbose:
    if line[0] == "verbose":
        verboselevel = int(line[1])
    #excludes:
    if line[0] == "exclude":
        excludes.append(line[1])
    ##backup dirs:
    #if line[0] == "backup":
    #    backups.append(line[1])
    #BACKUP DIR DEFINED BY SERVER, NOT BY CLIENT!
    if line[0] == "remote_server":
        remote_server = line[1]
    if line[0] == "port":
        port = int(line[1])

#check port existance:
if port == "":
    raise Exception("port was not found in config file..")
if remote_server = "":
    raise Exception("remote server was not found in config file..")

#snapshot_root:

if snapshot_root == "":
    raise Exception("snapshot_root was not defined in config file! aborting...")

if no_create_root == 1:
    #check if path exists:
    if os.path.exists(snapshot_root):
        #good!
        pass
    else:
        raise Exception("snapshot_root not existing. Maybe USB drive was not mounted. Aborting...")
else:
    if os.path.exists(snapshot_root):
        #good!
        pass
    else:
        os.makedirs(snapshot_root)

#check if timeinterval is in retain:
if not timeinterval in [eintrag[0] for eintrag in retains]:
    raise Exception("timeinterval not defined in config path!")

#which retain-ID is it?:
ID = 0
for retainID in xrange(len(retains)):
    if retains[retainID][0] == timeinterval:
        break
    else:
        ID+=1

#retains magic:
# retains is sorted by frequency, meaning the first entry should be done more often than the second.. and so on
#so check how many backups already have been done for the first one:

backupdir = os.path.join(snapshot_root, remote_server)
backupdirpathlist = os.listdir(backupdir)

for retainID in xrange(ID):
    #check if all backups are done yet:
    for amount in xrange(retains[retainID][1]):
        dir_should_exist = timeinterval + "." + str(amount)
        if dir_should_exist not in backupdirpathlist:
            raise Exception("requested backup for time interval: " + timeinterval + ", but a time interval with higher frequency was not finished yet!")

if ID != 0:
    #just copy an older container instead of talking to the rsnapssl server:
    #TODO
    exit()

#else:
#this means that the highest frequent timeinterval is requested --> make a real update

#mv existing instances from .X to .X+1:
#so if retain is set to weekly 5, iterate from weekly.4 to weekly.0 and mv from weekly.4->weekly.5 to weekly.0->weekly.1
#if existing, delete weekly.5!
amount = retains[0][1]
dir_to_excessive_backup=os.path.join(backupdir, timeinterval+"."+str(amount))
if os.path.exists(dir_to_excessive_backup):
    shutil.rmtree(dir_to_excessive_backup)
for i in range(amount)[::-1]: 
    mvcommand = "mv %s %s"%(os.path.join(backupdir, timeinterval + "." + str(amount)), os.path.join(backupdir, timeinterval + "." + str(amount+1)))
    print "running: " + mvcommand
    os.system(mvcommand)
#cp backup with cp -al:
cpcommand = "cp -al %s %s"%(os.path.join(backupdir, timeinterval + ".1"), os.path.join(backupdir, timeinterval + ".0"))
os.system(cpcommand)

#now read internal size/timestamp/dir database:
#it is by the way automatically located here:
database_path = os.path.join(backupdir, "database", "pydatabase.py")
if not os.path.exists(database_path):
    #at least create the dir:
    database_directory = os.path.split(database_path)[0]
    if not os.path.exists(database_directory):
        os.mkdir(database_directory)
    #and create an empty database:
    database = {}
else:
    #read the database:
    database = eval(open(database_path).read())

#now get database from remote host:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(s,
                           ca_certs="/etc/ca_certs_file",
                           cert_reqs=ssl.CERT_REQUIRED)
ssl_sock.connect((remote_server, port))
ssl_sock.write(b"GETFILELIST")
